home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / c / ctags.lha / ctags-3.0.3 / parse.c < prev    next >
C/C++ Source or Header  |  1999-02-17  |  59KB  |  2,165 lines

  1. /*****************************************************************************
  2. *   $Id: parse.c,v 7.4 1998/12/20 05:57:12 darren Exp $
  3. *
  4. *   Copyright (c) 1996-1998, Darren Hiebert
  5. *
  6. *   This source code is released for free distribution under the terms of the
  7. *   GNU General Public License.
  8. *
  9. *   This module contains functions for parsing and scanning of a source file.
  10. *****************************************************************************/
  11.  
  12. /*============================================================================
  13. =   Include files
  14. ============================================================================*/
  15. #include "general.h"
  16.  
  17. #include <string.h>
  18. #include <setjmp.h>
  19.  
  20. #include "ctags.h"
  21. #include "debug.h"
  22. #include "entry.h"
  23. #include "get.h"
  24. #include "keyword.h"
  25. #include "main.h"
  26. #include "options.h"
  27. #include "parse.h"
  28. #include "read.h"
  29.  
  30. /*============================================================================
  31. =   Macros
  32. ============================================================================*/
  33. #define MaxFields   2
  34.  
  35. #define stringValue(a)        #a
  36. #define activeToken(st)        ((st)->token[(int)(st)->tokenIndex])
  37. #define parentDecl(st)        ((st)->parent == NULL ? \
  38.                 DECL_NONE : (st)->parent->declaration)
  39. #define isType(token,t)        (boolean)((token)->type == (t))
  40. #define isMember(st)        (boolean)((st)->member.isMember)
  41. #define insideEnumBody(st)    (boolean)((st)->parent == NULL ? FALSE : \
  42.                     ((st)->parent->declaration == DECL_ENUM))
  43. #define isExternCDecl(st,c)    (boolean)((c) == STRING_SYMBOL  && \
  44.             !(st)->haveQualifyingName  && (st)->scope == SCOPE_EXTERN)
  45.  
  46. #define isOneOf(c,s)        (boolean)(strchr((s), (c)) != NULL)
  47.  
  48. /*============================================================================
  49. =   Data declarations
  50. ============================================================================*/
  51.  
  52. enum { NumTokens = 3 };
  53.  
  54. typedef enum eException {
  55.     ExceptionNone, ExceptionEOF, ExceptionFormattingError,
  56.     ExceptionBraceFormattingError
  57. } exception_t;
  58.  
  59. /*  Used to specify type of keyword.
  60.  */
  61. typedef enum eKeywordId {
  62.     KEYWORD_NONE,
  63.     KEYWORD_ATTRIBUTE, KEYWORD_ABSTRACT,
  64.     KEYWORD_BOOLEAN, KEYWORD_BYTE,
  65.     KEYWORD_CATCH, KEYWORD_CHAR, KEYWORD_CLASS, KEYWORD_CONST,
  66.     KEYWORD_DOUBLE,
  67.     KEYWORD_ENUM, KEYWORD_EXPLICIT, KEYWORD_EXTERN, KEYWORD_EXTENDS,
  68.     KEYWORD_FINAL, KEYWORD_FLOAT, KEYWORD_FRIEND,
  69.     KEYWORD_IMPLEMENTS, KEYWORD_IMPORT, KEYWORD_INLINE, KEYWORD_INT,
  70.     KEYWORD_INTERFACE,
  71.     KEYWORD_LONG,
  72.     KEYWORD_MUTABLE,
  73.     KEYWORD_NAMESPACE, KEYWORD_NEW, KEYWORD_NATIVE,
  74.     KEYWORD_OPERATOR, KEYWORD_OVERLOAD,
  75.     KEYWORD_PACKAGE, KEYWORD_PRIVATE, KEYWORD_PROTECTED, KEYWORD_PUBLIC,
  76.     KEYWORD_REGISTER,
  77.     KEYWORD_SHORT, KEYWORD_SIGNED, KEYWORD_STATIC, KEYWORD_STRUCT,
  78.     KEYWORD_SYNCHRONIZED,
  79.     KEYWORD_TEMPLATE, KEYWORD_THROW, KEYWORD_THROWS, KEYWORD_TRANSIENT,
  80.     KEYWORD_TRY, KEYWORD_TYPEDEF, KEYWORD_TYPENAME,
  81.     KEYWORD_UNION, KEYWORD_UNSIGNED, KEYWORD_USING,
  82.     KEYWORD_VIRTUAL, KEYWORD_VOID, KEYWORD_VOLATILE,
  83.     KEYWORD_WCHAR_T
  84. } keywordId;
  85.  
  86. /*  Used to determine whether keyword is valid for the current language and
  87.  *  what its ID is.
  88.  */
  89. typedef struct sKeywordDesc {
  90.     const char *name;
  91.     keywordId id;
  92.     short isValid[LANG_COUNT]; /* indicates languages for which kw is valid */
  93. } keywordDesc;
  94.  
  95. /*  Used for reporting the type of object parsed by nextToken().
  96.  */
  97. typedef enum eTokenType {
  98.     TOK_NONE,        /* none */
  99.     TOK_ARGS,        /* a parenthetical pair and its contents */
  100.     TOK_BRACE_CLOSE,
  101.     TOK_BRACE_OPEN,
  102.     TOK_COMMA,        /* the comma character */
  103.     TOK_KEYWORD,
  104.     TOK_NAME,        /* an unknown name */
  105.     TOK_PACKAGE,    /* a Java package name */
  106.     TOK_PAREN_NAME,    /* a single name in parentheses */
  107.     TOK_SEMICOLON,    /* the semicolon character */
  108.     TOK_SPEC,        /* a storage class specifier, qualifier, type, etc. */
  109.     TOK_COUNT
  110. } tokenType;
  111.  
  112. /*  This describes the scoping of the current statement.
  113.  */
  114. typedef enum eTagScope {
  115.     SCOPE_GLOBAL,        /* no storage class specified */
  116.     SCOPE_STATIC,        /* static storage class */
  117.     SCOPE_EXTERN,        /* external storage class */
  118.     SCOPE_FRIEND,        /* declares access only */
  119.     SCOPE_TYPEDEF,        /* scoping depends upon context */
  120.     SCOPE_COUNT
  121. } tagScope;
  122.  
  123. typedef enum eDeclaration {
  124.     DECL_NONE,
  125.     DECL_BASE,            /* base type (default) */
  126.     DECL_CLASS,
  127.     DECL_ENUM,
  128.     DECL_FUNCTION,
  129.     DECL_IGNORE,        /* non-taggable "declaration" */
  130.     DECL_INTERFACE,
  131.     DECL_NAMESPACE,
  132.     DECL_NOMANGLE,        /* C++ name demangling block */
  133.     DECL_PACKAGE,
  134.     DECL_STRUCT,
  135.     DECL_UNION,
  136.     DECL_COUNT
  137. } declType;
  138.  
  139. typedef enum eVisibilityType {
  140.     ACCESS_UNDEFINED,
  141.     ACCESS_PRIVATE,
  142.     ACCESS_PROTECTED,
  143.     ACCESS_PUBLIC,
  144.     ACCESS_COUNT
  145. } accessType;
  146.  
  147. /*  Information about the parent class of a member (if any).
  148.  */
  149. typedef struct sMemberInfo {
  150.     boolean    isMember;    /* is declared entity a member? */
  151.     boolean    immediate;    /* immediate class name preceding declaration?*/
  152.     accessType    access;        /* access of current statement */
  153.     accessType    accessDefault;    /* access default for current statement */
  154. } memberInfo;
  155.  
  156. typedef struct sTokenInfo {
  157.     tokenType     type;
  158.     keywordId     keyword;
  159.     vString *     name;        /* the name of the token */
  160.     unsigned long lineNumber;    /* line number of tag */
  161.     fpos_t        filePosition;    /* file position of line containing name */
  162. } tokenInfo;
  163.  
  164. /*  Describes the statement currently undergoing analysis.
  165.  */
  166. typedef struct sStatementInfo {
  167.     tagScope    scope;
  168.     declType    declaration;    /* specifier associated with TOK_SPEC */
  169.     boolean    gotName;    /* was a name parsed yet? */
  170.     boolean    haveQualifyingName;  /* do we have a name we are considering? */
  171.     boolean    gotParenName;    /* was a name inside parentheses parsed yet? */
  172.     boolean    gotArgs;    /* was a list of parameters parsed yet? */
  173.     boolean    isPointer;    /* is 'name' a pointer? */
  174.     unsigned int tokenIndex;    /* currently active token */
  175.     tokenInfo *    token[(int)NumTokens];
  176.     tokenInfo *    context;    /* information on name of current context */
  177.     memberInfo    member;        /* information regarding parent class/struct */
  178.     struct sStatementInfo *parent;  /* statement we are nested within */
  179. } statementInfo;
  180.  
  181. /*  Describes the type of tag being generated.
  182.  */
  183. typedef enum eTagType {
  184.     TAG_UNDEFINED,
  185.     TAG_CLASS,            /* class name */
  186.     TAG_ENUM,            /* enumeration name */
  187.     TAG_ENUMERATOR,        /* enumerator (enumeration value) */
  188.     TAG_FIELD,            /* field (Java) */
  189.     TAG_FUNCTION,        /* function definition */
  190.     TAG_INTERFACE,        /* interface declaration */
  191.     TAG_MEMBER,            /* structure, class or interface member */
  192.     TAG_METHOD,            /* method declaration */
  193.     TAG_NAMESPACE,        /* namespace name */
  194.     TAG_PACKAGE,        /* package name */
  195.     TAG_PROTOTYPE,        /* function prototype or declaration */
  196.     TAG_STRUCT,            /* structure name */
  197.     TAG_TYPEDEF,        /* typedef name */
  198.     TAG_UNION,            /* union name */
  199.     TAG_VARIABLE,        /* variable definition */
  200.     TAG_EXTERN_VAR,        /* external variable declaration */
  201.     TAG_COUNT            /* must be last */
  202. } tagType;
  203.  
  204. typedef struct sParenInfo {
  205.     boolean isPointer;
  206.     boolean isParamList;
  207.     boolean isKnrParamList;
  208.     boolean isNameCandidate;
  209.     boolean invalidContents;
  210.     boolean nestedArgs;
  211.     unsigned int parameterCount;
  212. } parenInfo;
  213.  
  214. /*============================================================================
  215. =   Data definitions
  216. ============================================================================*/
  217.  
  218. static jmp_buf Exception;
  219.  
  220. static const keywordDesc KeywordTable[] = {
  221.     /*                             C++        */
  222.     /*                          ANSI C  |  Java    */
  223.     /* keyword        keyword ID         \   |   /      */
  224.     { "__attribute__",    KEYWORD_ATTRIBUTE,    { 1, 1, 0 } },
  225.     { "abstract",    KEYWORD_ABSTRACT,    { 0, 0, 1 } },
  226.     { "boolean",    KEYWORD_BOOLEAN,    { 0, 0, 1 } },
  227.     { "byte",        KEYWORD_BYTE,        { 0, 0, 1 } },
  228.     { "catch",        KEYWORD_CATCH,        { 0, 1, 0 } },
  229.     { "char",        KEYWORD_CHAR,        { 1, 1, 1 } },
  230.     { "class",        KEYWORD_CLASS,        { 0, 1, 1 } },
  231.     { "const",        KEYWORD_CONST,        { 1, 1, 1 } },
  232.     { "double",        KEYWORD_DOUBLE,        { 1, 1, 1 } },
  233.     { "enum",        KEYWORD_ENUM,        { 1, 1, 0 } },
  234.     { "explicit",    KEYWORD_EXPLICIT,    { 0, 1, 0 } },
  235.     { "exte